#ifndef _CONTROL_COWSERVER_H_
#define _CONTROL_COWSERVER_H_

#include "thread.h"
#include "singleton.h"
#include "tcpclient.h"
#include "tcpserver.h"
#include "mysqlmgr.h"
#include "config.h"

/////////////////////////////////   CCowSyncClient      ///////////////////////////////////

class CCowSyncClient : public CSyncTcpClient
{
    friend class CCowWork;

public:

    CCowSyncClient();

    virtual ~CCowSyncClient();
    
    virtual int OnRecvMsg(const char* inbuf, int inlen);

private:

    RecvBlockQueue m_recvqueue;
};

/////////////////////////////////   CCowClient      ///////////////////////////////////

class CCowCmd;

class CCowClient : public CTcpClient
{
    friend class CCowWork;

public:

    CCowClient();

    virtual ~CCowClient();

    bool GetOutCmd(CCowCmd* outcmd);
    
    virtual int OnRecvMsg(const char* inbuf, int inlen);

private:

    RecvBlockQueue m_recvqueue;
};

/////////////////////////////////   CCowServer      ///////////////////////////////////

class CCowServer : public CTcpServer
{
    friend class CCowWork;

public:

    CCowServer();

    virtual ~CCowServer();

    virtual int OnRecvMsg(const char* addrinfo, const char* inbuf, int inlen);

private:

    RecvBlockQueue m_recvqueue;
};

/////////////////////////////////   CCowWork      ///////////////////////////////////

class CCowWork
{
    friend class CSingleton<CCowWork>;

    friend THREAD_HANDLE(cow_work_thread, param);

    CCowWork();

    bool  m_isrun;

    bool  m_isserver;

    CConfig m_config;

public:

    ~CCowWork();

    bool Start(const char* configname);

private:

    void Clean();

public: /***********   CCowSyncClient      *************/

    bool StartSyncClient();

    bool SyncWork(CCowCmd* incmd, CCowCmd* outcmd);

private:

    CCowSyncClient* m_syncclient;


public: /***********   CCowClient      *************/

    bool StartClient();
    
    bool GetOutCmd(CCowCmd* outcmd);

    bool PushInCmd(CCowCmd* incmd);

    void SetClientCallback(socket_callback_func func);
    
private:

    CCowClient* m_client;


public: /***********   CCowServer      *************/

    bool StartServer();

private:

    void WorkThread(int index);

    int m_workthreadcount;

    CThread** m_workthreads;

    CCowServer** m_servers;

    CCowMysql** m_mysqls;
};

#define sCowWork CSingleton<CCowWork>::Instance()

#endif //_CONTROL_COWSERVER_H_
